package cn.com.jdk.proxy;

import cn.com.jdk.point.Point;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class ActiveProxy implements InvocationHandler {

    /**
     * 切点
     */
    private Point point;

    /**
     * 代理对象
     */
    private Object obj;

    /**
     * 需要增强的方法
     */
    private List<String> enhanceMethodList;

    /**
     * 是否全部增强
     */
    private boolean isAllEnhance = true;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        Exception exception = null;
        /**
         * 判断
         * 是否全部增强
         * 如果不是全部增强，增强方法是否属于指定的方法
         */
        if (isAllEnhance || (!isAllEnhance && !CollectionUtils.isEmpty(enhanceMethodList)
                && enhanceMethodList.contains(method.getName()))) {
            boolean flag = point.before(args);
            if(flag){
                try {
                    result = method.invoke(obj, args);
                } catch (Exception e) {
                    e.printStackTrace();
                    exception = e;
                }
                point.after(result, exception, args);
            }
        }else{
            result = method.invoke(obj, args);
        }
        return result;
    }

    /**
     * 创建代理对象
     * @param clazz 代理对象的接口类clazz
     * @param obj 代理对象实例
     * @param point 切点实例
     * @param <T>
     * @return
     */
    public <T> T createObj(Class<T> clazz,T obj,Point point){
        this.obj = obj;
        this.point = point;
        T t = (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, this);
        return t;
    }


    public <T> T createObj(Class<T> clazz,T obj,Point point,boolean isAllEnhance,List<String> enhanceMethodList){
        this.isAllEnhance = isAllEnhance;
        this.enhanceMethodList = enhanceMethodList;
        return createObj(clazz,obj,point);
    }
}
